/**
 * 
 */
package com.nari.baseinfo.dao;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Date;

import com.nari.baseinfo.model.IFileMapping;
import com.nari.coreframe.dao.hibernate3.GenericDaoImpl;
import com.nari.platform.date.CalendarUtils;
import com.nari.platform.model.ResponseMsg;

/**
 * 附件实体映射通用管理DAO
 * @author Xiaopeng
 * @date 2013-8-9
 */
public class FileMappingDaoImpl extends GenericDaoImpl<IFileMapping, String> implements
		IFileMappingDao {
	private static final int BUFFER_SIZE = 20*1024; //设置文件上传缓存20K
	
	/**
	 * 通过文件映射唯一标识删除附件信息
	 * @param fileMapUID
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-12
	 */
	public void deleteFileMapByUID(String fileMapUID) throws Exception {
		IFileMapping fileMapping = this.queryEntityById(fileMapUID);
		if(fileMapping != null) {
			//删除磁盘附件
			File attachFile = new File(fileMapping.getDiskID() + "/" + fileMapping.getSavePath());
			if(attachFile.exists()) attachFile.delete();
			//删除文件映射
			this.deleteEntityById(fileMapUID);
		}
	}
	
	/**
	 * 保存上传文件到指定的目录中
	 * @param src 源上传缓存文件
	 * @param dest 目标保存文件
	 * @return
	 * @throws Exception 返回上传结果标志位
	 * @author Xiaopeng
	 * @date 2013-10-28
	 */
	public int saveUpload(File src, File dest) throws Exception {
		BufferedOutputStream bos = 
				new BufferedOutputStream(new FileOutputStream(dest), BUFFER_SIZE);
		BufferedInputStream bis = 
				new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
		int length;
		byte[] buffer = new byte[BUFFER_SIZE];
		while((length=bis.read(buffer))!=-1){
			bos.write(buffer, 0, length);
		}
		bos.close();
		bis.close();
		return 1;
	}
	
	/**
	 * 附件上传存储
	 * @param attachFile 上传附件
	 * @param fileName 附件名称
	 * @param diskSavePath 附件存储的磁盘目录
	 * @param relSaveFolder 附件存储的相对目录(文件夹目录)
	 * @return 
	 * 返回信息说明：
	 * 1、附件上传成功，返回附件实体映射UID；
	 * 2、附件上传失败，返回失败信息
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-4-19
	 */
	public ResponseMsg saveAttachmentUpload(File attachFile, String fileName, 
			String diskSavePath, String relSaveFolder) throws Exception {
		if(attachFile != null) {
			//附件实体映射
			IFileMapping fileMapping = null;
			//存储磁盘附件
			File svFile = null; 
			try {
				//附件存储路径对应的磁盘目录检测
				File fileSaveFolder = new File(diskSavePath + "/" + relSaveFolder);
				if(!fileSaveFolder.exists()) fileSaveFolder.mkdirs();
				//文件名称
				String orFilename = fileName.substring(0, fileName.lastIndexOf("."));
				//文件类型
				String fileType = fileName.substring(fileName.lastIndexOf(".")+1);
				//附件实体映射实例化
				fileMapping = new IFileMapping();
				fileMapping.setOrFilename(orFilename);
				fileMapping.setDiskID(diskSavePath);
				fileMapping.setFileType(fileType);
				fileMapping.setFileSize(attachFile.length());
				fileMapping.setCreateTime(new Date());
				//读取文件映射的唯一标识
				String fileMappingUID = this.saveEntity(fileMapping);
				//文件存储的随机文件名(添加实体映射UID，便于服务器附件识别调试)
				String svFilename = fileMappingUID + "-" + CalendarUtils.parseDateToString(new Date(), "yyyy-MM-dd-HH-mm-ss");
				fileMapping.setSvFilename(svFilename);
				//文件的存储路径(相对路径)
				String savePath = relSaveFolder + "/" + svFilename + "." + fileType;
				fileMapping.setSavePath(savePath);
				this.updateEntity(fileMapping, fileMappingUID);
				//将附件文件保存到磁盘中
				svFile = new File(diskSavePath + "/" + savePath);
				this.saveUpload(attachFile, svFile);
			} catch (Exception e) {
				e.printStackTrace();
				if(svFile.exists()) svFile.delete();
				throw new Exception(e.getMessage());
			}
			if(fileMapping != null) {
				return ResponseMsg.getInstance(true, fileMapping.getId());
			}
		}
		return ResponseMsg.getInstance(false, "无法识别的上传附件，请检查后重新上传！");
	}
	
}
